﻿using System;
using Microsoft.SharePoint;
using Microsoft.SharePoint.WebControls;
using System.IO;
using ServBus.ListForm2010.Utility;
using System.Collections.Generic;

namespace ServBus.ListForm2010.Layouts.InfoBus2010
{
    public partial class ListFormCustomize : LayoutsPageBase
    {
        private SPList mList;
        private SPWeb mWeb;
        private SPSite mSite;
        private InfoPathContext context;
        private string cTypeResrouceFolder;
        private string contentTypeName;

        protected void downloadFileClick(Exception ex)
        {
            LTException.Text = ex.ToString();
            errorPanel.Visible = true;
            ErrorLog.Write("ListFormCustomize" + "\r\n" + Request.Url + "\r\n" + ex.Message + "\r\n" + ex.StackTrace, System.Diagnostics.EventLogEntryType.Error);

        }

        #region Page Method
        
        protected void Page_Load(object sender, EventArgs e)
        {
            //Response.Write("<script type='text/javascript'>window.frameElement.commitPopup('Operation Successful!')</script>");
            string listIdString = Page.Request["ListId"];
            Guid listId = new Guid(listIdString);
            try
            {
                string xsnLocation = "";
                string destFolderUrl = "";


                Guid _siteId = SPContext.Current.Site.ID;
                string _siteUrl = SPContext.Current.Site.Url;
                Guid _webId = SPContext.Current.Web.ID;

                SPSecurity.RunWithElevatedPrivileges(delegate()
                {
                    using (SPSite _site = new SPSite(_siteId))
                    {
                        using (SPWeb _web = Site.OpenWeb(_webId))
                        {
                            _web.AllowUnsafeUpdates = true;
                            SPList _list = _web.Lists[listId];
                            SPContentType _cType = _list.ContentTypes[0];
                            contentTypeName = _cType.Name;
                            //xsnLocation = _siteUrl + _cType.ResourceFolder.ServerRelativeUrl + "/template.xsn";
                            xsnLocation = _web.Url + "/" + _cType.ResourceFolder.Url + "/template.xsn";

                            if (!_web.GetFile(xsnLocation).Exists)
                            {
                                //contentTypeName = _cType.Name;
                                //display_lb.aspx, edit_lb.aspx, new_lb.aspx
                                destFolderUrl = _cType.ResourceFolder.ServerRelativeUrl;
                                string listParameter = "listId=" + _list.ID.ToString();
                                string cTypeParameter = "ctypeId=" + _cType.Id.ToString();
                                string uploadFileName = Microsoft.SharePoint.Utilities.SPUtility.GetGenericSetupPath(@"TEMPLATE\LAYOUTS\InfoBus2010\Template.aspx");
                                FileStream fileStream = File.Open(uploadFileName, FileMode.Open);
                                _web.Files.Add(destFolderUrl + "/display_lb.aspx", fileStream, true);
                                _cType.DisplayFormUrl = destFolderUrl + "/display_lb.aspx?" + listParameter + "%26" + cTypeParameter;
                                _web.Files.Add(destFolderUrl + "/edit_lb.aspx", fileStream, true);
                                _cType.EditFormUrl = destFolderUrl + "/edit_lb.aspx?" + listParameter + "%26" + cTypeParameter;
                                _web.Files.Add(destFolderUrl + "/new_lb.aspx", fileStream, true);
                                _cType.NewFormUrl = destFolderUrl + "/new_lb.aspx?" + listParameter + "%26" + cTypeParameter;


                                fileStream.Close();
                                _cType.Update();
                                _list.Update();

                                InitialContextVar(_siteUrl, _webId, listId);
                                cTypeResrouceFolder = _cType.ResourceFolder.Name;
                                context.ListContentTypeName = _cType.Name;
                                GenerateXSN();
                            }
                        }
                    }
                });
                //Response.Write("<script type='text/javascript'>window.frameElement.commitPopup('Operation Successful!')</script>");

                Response.Write("<script type='text/javascript'>var spOpener = new ActiveXObject('SharePoint.OpenXMLDocuments');if (spOpener != null) {var x = spOpener.CustomizeTemplate('" + xsnLocation + "'); }window.close();</script>");
                //Response.Write("<script type='text/javascript'>var spOpener = new ActiveXObject('SharePoint.OpenXMLDocuments');if (spOpener != null) {var x = spOpener.CustomizeTemplate ('" + xsnLocation + "'); }</script>");

            }
            catch (Exception ex)
            {
                downloadFileClick(ex);
            }
        }

        #endregion


        #region GenerateXSN

        private void InitialContextVar(string _siteUrl, Guid _webId, Guid _listId)
        {
            if (context == null)
            {
                context = new InfoPathContext();
            }
            mSite = new SPSite(_siteUrl);
            // 101
            context.CurrentSiteUrl = _siteUrl;

            context.XsnName = "template";
            mWeb = mSite.OpenWeb(_webId);
            context.Web = mWeb;
            mList = mWeb.Lists[_listId];
            context.ListName = mList.Title;
            context.PageUrl = Context.Request.Url;
            context.MainListFullUrl = context.CurrentSiteUrl + mList.RootFolder.ServerRelativeUrl;
        }

        private void GenerateXSN()
        {
            ListInfo keyListInfo = CreateListInfo();
            context.XsnName = "template";
            StartCreateInfoPath(keyListInfo);
            UploadFileToFormLib();
        }

        private void UploadFileToFormLib()
        {
            try
            {
                System.Threading.Thread.Sleep(1000);
                // SPUtility.CreateFolderUnderList(mWeb,mList.Title,"defaultInfoPath");
                string xsnNam = context.XsnName + ".xsn";
                string m_xsn_location = SPUtility.CreateFile(Site, Web, mList, cTypeResrouceFolder, xsnNam, GetXsnFileStream());

                context.XsnLocation = m_xsn_location;
                //SPList list = Web.Lists[NameSpaceConstants.Name_FormLib];
                //SPUtility.CreateFileUnderDocLib(Web, list, xsnNam, GetXsnFileStream());
            }
            catch (Exception ex)
            {
                LTException.Text = ex.ToString();
                errorPanel.Visible = true;
                //File.WriteAllText(@"c:\a1.txt", ex.ToString());
            }
            //SPUtility.ClearAllItemsInFolder(mList, mList.RootFolder.SubFolders["defaultInfoPath"]);
            //Dictionary<string, string> dic = new Dictionary<string, string>();
            //dic.Add("Title", context.XsnName);
            //SPListItem item = SPUtility.CreateItemUnderFolder(mList, mList.RootFolder.SubFolders["defaultInfoPath"], dic);
            //SPUtility.AddFileToListItem(mList,item, context.XsnName + "_infoPath" + ".xsn", GetXsnFileStream());
            //string desPath = mWeb.Url + "/" + mList.Title + "/defaultInfoPath/" + context.XsnName + "_infoPath" + ".xsn";
            //SPUtility.UploadFileToDocumentLibrary(context.XsnPath, desPath);
        }

        private byte[] GetXsnFileStream()
        {
            byte[] buf = new byte[100];
            List<byte> bytes = new List<byte>();
            using (FileStream fs = File.Open(context.XsnPath, FileMode.Open, FileAccess.Read))
            {
                int offset = 0;
                int len = 0;
                while ((len = fs.Read(buf, offset, buf.Length)) > 0)
                {
                    CopyOneStreamToStream(buf, bytes);
                    buf = new byte[100];
                }
            }

            return bytes.ToArray();
        }

        private void CopyOneStreamToStream(byte[] byte1, List<byte> byte2)
        {
            foreach (byte bt in byte1)
            {
                byte2.Add(bt);
            }
        }

        private void StartCreateInfoPath(ListInfo listInfo)
        {
            //先初始化模板文件的根目录和目标文件的根目录
            string templateFilePath = Server.MapPath("/_layouts/InfoBus2010/template/");
            string destPath = Server.MapPath("/_layouts/InfoBus2010/TempXsnFiles/");
            NameSpaceConstants.TemplateRootPath = templateFilePath;
            if (!Directory.Exists(NameSpaceConstants.Des_Root_Path))
            {
                Directory.CreateDirectory(NameSpaceConstants.Des_Root_Path);
            }

            context.MainListFields = listInfo.Fields;
            CreateFieldLogic cl = new CreateFieldLogic(listInfo, context);
            cl.BeginToCreate();
        }

        private ListInfo CreateListInfo()
        {
            List<string> litNames = new List<string>();
            litNames.Add(mList.Title);
            ListInfo keyListInfo = null;

            foreach (string litNam in litNames)
            {
                context.AddListNames(litNam);
                string ctrid = CreateRadbtnID(litNam);
                string ctName = contentTypeName;

                context.SelectedContent.Add(litNam, ctName);
                if (litNam == mList.Title)
                {
                    // Make key ListInfo, because the key list name is added firstly, 
                    // so the method can run correctly
                    keyListInfo = CreateListInfo(litNam, ctName);
                }
                else
                {
                    context.AddedSecondaryListNames.Add(litNam);
                    ListInfo subOrdinaryListInfo = CreateListInfo(litNam, ctName);
                    keyListInfo.LookupLists.Add(subOrdinaryListInfo);
                }
            }

            return keyListInfo;
        }

        private string CreateRadbtnID(string listTitle)
        {
            return string.Format("ctl00$PlaceHolderMain$sec{0}${0}##", listTitle);
        }

        private ListInfo CreateListInfo(string listTitle, string ctNam)
        {
            ListInfo listInfo = new ListInfo();
            listInfo.Name = listTitle;
            listInfo.Fields = new List<FieldInfo>();

            SPContentType ct = this.mWeb.Lists[listTitle].ContentTypes[ctNam];
            cTypeResrouceFolder = ct.ResourceFolder.Name;
            foreach (SPField fld in ct.Fields)
            {
                //TO DO..
                if (fld.StaticName == "ContentType")
                {
                    continue;
                }
                FieldInfo fldInfo = new FieldInfo();
                listInfo.Fields.Add(fldInfo.CreateFieldInfo(fld, mList, ct));
            }

            // id field is a special, so we need to add it specific.
            SPField field = mList.Fields["ID"];
            FieldInfo idInfo = new FieldInfo();
            listInfo.Fields.Add(idInfo.CreateFieldInfo(field, mList, ct));
            return listInfo;
        }

        #endregion

    }
}
